package com.cta.service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cta.dao.ReportPersistence;
import com.cta.dao.report.MasterDataDao;
import com.cta.entity.MasterData;
import com.cta.entity.Site;
import com.cta.service.report.ReportSqlBuilder;
import com.cta.view.json.tree.TariffEntityTreeNode;
import com.cta.view.model.report.PeriodParams;
import com.cta.view.model.report.ReportParams;

@Service
public class ReportService {

	private static final Logger log = LoggerFactory.getLogger(ReportService.class);

	@Autowired
	private ReportPersistence reportPersistence;

	@Autowired
	private SiteService siteService;

	@Autowired
	private MasterDataDao masterDataDao;

	@SuppressWarnings("rawtypes")
	public List<TariffEntityTreeNode> loadEntity() {
		// load all site
		List<Site> sites = siteService.findAllSites();
		List<Long> siteIds = new ArrayList<Long>(sites.size());
		List<TariffEntityTreeNode> results = new ArrayList<TariffEntityTreeNode>(sites.size());
		for (Site site : sites) {
			siteIds.add(site.getId());
			results.add(new TariffEntityTreeNode(site.getParentId(), site.getId(), site.getName()));
		}
		// find all pbx and contact
		if (siteIds.size() > 0) {
			List<Object[]> loadAllContactPbx = reportPersistence.loadAllContactPbx(siteIds);
			Map<Long, List<TariffEntityTreeNode>> temp = new HashMap<Long, List<TariffEntityTreeNode>>();
			if (loadAllContactPbx.size() > 0) {
				for (Object[] map : loadAllContactPbx) {
					Long parentId = ((BigInteger) map[2]).longValue();
					List<TariffEntityTreeNode> tlist = temp.get(parentId);
					if (tlist == null) {
						tlist = new ArrayList<TariffEntityTreeNode>();
						temp.put(parentId, tlist);
					}

					tlist.add(new TariffEntityTreeNode(parentId, ((BigInteger) map[1]).longValue(), (String) map[0],
							(String) map[3]));
				}
			}
			// merge all children to site
			for (TariffEntityTreeNode node : results) {
				List<TariffEntityTreeNode> list = temp.get(node.getObId());
				if (list != null) {
					node.getChildren().addAll(list);
				}
			}
			// build tree
			results = getChildrenTreeList(results, null);
		}
		return results;
	}

	private List<TariffEntityTreeNode> getChildrenTreeList(List<TariffEntityTreeNode> treeList, Long nodeId) {
		List<TariffEntityTreeNode> childrenList = new ArrayList<TariffEntityTreeNode>();

		if (treeList != null && treeList.size() > 0) {
			for (TariffEntityTreeNode sitemap : treeList) {

				boolean addChildren = false;
				if (nodeId == null) {
					addChildren = ((nodeId == sitemap.getParentId()) || (0 == sitemap.getParentId()));
				} else {
					addChildren = (nodeId.equals(sitemap.getParentId()));
				}

				if (addChildren) {
					List<TariffEntityTreeNode> list = getChildrenTreeList(treeList, sitemap.getObId());
					// merge content component and child page
					sitemap.getChildren().addAll(0, list);
					if (list != null && list.size() > 0) {
						sitemap.setLeaf(false);
					}
					childrenList.add(sitemap);
				}
			}
		}

		return childrenList;
	}

	public void runReport(ReportParams params) {
		// parsing param
		PeriodParams period = params.getPeriod();
		if (period != null) {
			Date fromDate = null, toDate = null;
			if ("preset".equals(period.getType())) {
				String presetValue = period.getPresetValue();
				if (PeriodParams.TODAY.equals(presetValue)) {

					LocalDateTime today = new LocalDateTime();
					fromDate = today.withTime(0, 0, 0, 0).toDate();
					toDate = today.withTime(23, 59, 59, 999).toDate();

				} else if (PeriodParams.YESTERDAY.equals(presetValue)) {

					LocalDateTime today = new LocalDateTime();
					today = today.minusDays(1);
					fromDate = today.withTime(0, 0, 0, 0).toDate();
					toDate = today.withTime(23, 59, 59, 999).toDate();

				} else if (PeriodParams.THIS_WEEK.equals(presetValue)) {

					LocalDateTime today = new LocalDateTime();
					fromDate = today.dayOfWeek().withMinimumValue().withTime(0, 0, 0, 0).toDate();
					toDate = today.dayOfWeek().withMaximumValue().withTime(23, 59, 59, 999).toDate();

				} else if (PeriodParams.LAST_WEEK.equals(presetValue)) {

					LocalDateTime today = new LocalDateTime();
					today = today.minusWeeks(1);
					fromDate = today.dayOfWeek().withMinimumValue().withTime(0, 0, 0, 0).toDate();
					toDate = today.dayOfWeek().withMaximumValue().withTime(23, 59, 59, 999).toDate();

				} else if (PeriodParams.THIS_MONTH.equals(presetValue)) {

					LocalDateTime today = new LocalDateTime();
					fromDate = today.dayOfMonth().withMinimumValue().withTime(0, 0, 0, 0).toDate();
					toDate = today.dayOfMonth().withMaximumValue().withTime(23, 59, 59, 999).toDate();

				} else if (PeriodParams.LAST_MONTH.equals(presetValue)) {

					LocalDateTime today = new LocalDateTime();
					today = today.minusMonths(1);
					fromDate = today.dayOfMonth().withMinimumValue().withTime(0, 0, 0, 0).toDate();
					toDate = today.dayOfMonth().withMaximumValue().withTime(23, 59, 59, 999).toDate();

				} else if (PeriodParams.THIS_YEAR.equals(presetValue)) {
					LocalDateTime today = new LocalDateTime();
					fromDate = today.dayOfYear().withMinimumValue().withTime(0, 0, 0, 0).toDate();
					toDate = today.dayOfYear().withMaximumValue().withTime(23, 59, 59, 999).toDate();
				}
			} else if ("last".equals(period.getType())) {
				String lastValue = period.getLastValue();
				int lastTime = period.getLastTime();

				if (PeriodParams.HOURS.equals(lastValue)) {

					LocalDateTime today = new LocalDateTime();
					toDate = today.toDate();
					today = today.minusHours(lastTime);
					fromDate = today.toDate();

				} else if (PeriodParams.DAYS.equals(lastValue)) {

					LocalDateTime today = new LocalDateTime();
					toDate = today.toDate();
					today = today.minusDays(lastTime);
					fromDate = today.toDate();

				} else if (PeriodParams.WEEKS.equals(lastValue)) {

					LocalDateTime today = new LocalDateTime();
					toDate = today.toDate();
					today = today.minusWeeks(lastTime);
					fromDate = today.toDate();

				} else if (PeriodParams.MONTHS.equals(lastValue)) {

					LocalDateTime today = new LocalDateTime();
					toDate = today.toDate();
					today = today.minusMonths(lastTime);
					fromDate = today.toDate();

				} else {

					LocalDateTime today = new LocalDateTime();
					toDate = today.toDate();
					today = today.minusYears(lastTime);
					fromDate = today.toDate();

				}

			} else {
				// from
				fromDate = period.getFromDate();
				toDate = period.getToDate();
			}

			// lookup what table will be get data from
			List<MasterData> tables = masterDataDao.lookups(fromDate, toDate);
			String sql = ReportSqlBuilder.buildSql(tables, params.getType(), params.getEntity(), fromDate, toDate);
			
			
			System.out.println("from " + fromDate);
			System.out.println("to   " + toDate);
			System.out.println("sql  " + sql);
			
			if(StringUtils.isNotEmpty(sql)){
				
			}
		}

	}
}
